import { SearchOutlined } from '@ant-design/icons'
import { truthy } from '@gnlab/utils'
import { Input, Tag, Button, Select, Checkbox } from 'antd'
import uniq from 'lodash/uniq'
import AutoSizer from 'react-virtualized-auto-sizer'
import { FixedSizeList as List } from 'react-window'
import { Loading, Empty } from '@/desktop/components'
import ChooseExternalTagsModal from '@/desktop/components/ChooseExternalTags'
import  defaultAvatar  from '@/desktop/assets/avatar.jpg'
import { type ExternalContact } from '@/services/contact-types'
import type { AccountQywx } from '@/services/qywxs'
import {
  type Cache,
  type Choosed,
  useTags,
  useFocusTagContacts,
  type ChoosingItem,
  useChooseTagContacts,
} from './logics'
import './by-tags.module.less'

export function ByTags(props: {
  cache: Cache
  configQywxs: AccountQywx[]
  choosed: Choosed // 已选中联系人
  choose: (contacts: ExternalContact[], isChoosed: boolean, tagId: string) => void // 更新选中联系人
  setChoosed: (choosed: Choosed) => void
}) {
  const { cache, configQywxs, choosed, setChoosed } = props

  const {
    tags,
    focusTag,
    setFocusTag,
    startUpdate,
    updated,
    updating,
    tagsInitializing,
    removeTag,
  } = useTags(cache, configQywxs, choosed, setChoosed)

  const {
    loading: loadingContacts,
    contacts: focusContacts,
    choosingItems,
    filterKeyword,
    setFilterKeyword,
    filterWxid,
    setFilterWxid,
  } = useFocusTagContacts(cache, configQywxs, focusTag, choosed, setChoosed)

  const { switchChoose, allChoosed, chooseAll } = useChooseTagContacts(
    focusTag,
    choosingItems,
    choosed,
    setChoosed,
  )

  // ===============================================

  // 此函数每次重新生成，会导致列表里的元素都重新“生成“（不是重新渲染，是重新生成组件并挂载），因此尽量不要有依赖
  const Item = useCallback(
    ({
      data,
      index,
      style,
    }: {
      data: ChoosingItem[]
      index: number
      style: React.CSSProperties
    }) => {
      const { choosed, contact, qywx } = data[index]!
      return <div style={style} styleName="contact-row" onClick={() => switchChoose(contact.id)}>
        <div styleName="choose">
          <Checkbox checked={choosed}></Checkbox>
        </div>
        <div styleName="contact">
          <img loading="lazy" src={contact.avatar || defaultAvatar} />
          <div styleName="name">{contact.name}</div>
        </div>
        <div styleName="qywx">{qywx.friendlyFullName}</div>
      </div>
    },
    [switchChoose],
  )

  const itemKey = useCallback((index: number, list: ChoosingItem[]) => list[index]!.contact.id, [])

  return <div styleName="choose-by-tags">
    {/* ===== Tags / Filter ===== */}
    {!tags.length ? (
      <Empty
        styleName="no-tags"
        description={
          <div>
            尚未选择标签，<a onClick={startUpdate}>点此选择</a>
          </div>
        }
      />
    ) : (
      <header>
        <div styleName="tags-row">
          <label>标签列表</label>
          <div>
            {tags.map(tag => {
              const tagChoosed = choosed.get(tag.id)?.size ?? 0
              return <Tag
                key={tag.id}
                color={focusTag?.id === tag.id ? 'blue' : ''}
                onClick={() => setFocusTag(tag)}
                closable
                onClose={() => removeTag(tag.id)}
              >
                <span>{tag.name}</span>
                {tagChoosed ? (
                  <span styleName="count">{tagChoosed > 99 ? '99+' : tagChoosed}</span>
                ) : null}
              </Tag>
            })}
            <Button onClick={startUpdate} type="link">
              选择标签
            </Button>
          </div>
        </div>

        {truthy(focusContacts?.length) ? (
          <div styleName="search-row">
            <label>搜索客户</label>
            <Input
              prefix={<SearchOutlined />}
              placeholder="输入关键词"
              value={filterKeyword}
              onChange={e => setFilterKeyword(e.target.value)}
            />
            <Select
              allowClear
              placeholder="企微账号"
              options={configQywxs.map(qywx => ({
                label: qywx.friendlyFullName,
                value: qywx.wxid,
              }))}
              value={filterWxid}
              onChange={setFilterWxid}
            />
          </div>
        ) : null}
      </header>
    )}

    {tagsInitializing ? <Loading styleName="loading-mask" tip="正在初始化选中客户..." /> : null}

    <ChooseExternalTagsModal
      visible={updating}
      title="选择标签"
      corpIds={uniq(configQywxs.map(qywx => qywx.corpid))}
      choosed={tags.map(v => v.id)}
      onFinish={updated}
    />

    {/* ===== Contacts ===== */}
    <main>
      {tags.length && !focusTag ? (
        <Empty styleName="empty" description={<div>点击上方标签，选择客户</div>} />
      ) : null}

      {loadingContacts ? <Loading styleName="loading-mask" tip="正在加载联系人..." /> : null}

      {focusContacts && !focusContacts.length ? (
        <Empty styleName="empty" description="此标签下没有客户" />
      ) : null}

      {truthy(focusContacts?.length) && !choosingItems.length ? (
        <Empty styleName="empty" description="没有匹配的客户" />
      ) : null}

      {choosingItems.length ? (
        <>
          <div styleName="contacts-header">
            <div styleName="choose">
              <Checkbox
                disabled={allChoosed === null}
                checked={allChoosed === 2}
                indeterminate={allChoosed === 1}
                onClick={chooseAll}
              />
            </div>
            <div styleName="contact">客户</div>
            <div styleName="qywx">所属企微</div>
          </div>
          <div styleName="contacts-wrapper">
            <AutoSizer>
              {({ width, height }) => <List
                height={height}
                width={width}
                itemCount={choosingItems.length}
                itemSize={70}
                itemData={choosingItems}
                itemKey={itemKey}
              >
                {Item}
              </List>}
            </AutoSizer>
          </div>
        </>
      ) : null}
    </main>
  </div>
}
